r"""Limiter functions for the WAF flux.

These limiters are described in Toro's book (section 14.3.4) 

"""

class WAFLimiter(object):
    """Base class for all WAF limiters

    All the WAF limiters are a one dimensional function of two
    arguments :math:`\phi(r^k, |c_k|)`

    """
    def limit(self, r, cabs):
        """Return the limiting constant.

        **Parameters**:

        r : float
            The flow parameter.

        ckabs : float
            The absolute value of the courant number

        """
        raise NotImplementedError("WAFLimiter::limit called")

class UpwindLimiter(WAFLimiter):
    r"""Upwind limiter for the WAF flux given by:

    .. math::

        \phi(r, |c|) = 1
        
    """
    def limit(self, r, cabs):
        return 1.0
        
class SuperBeeLimiter(WAFLimiter):
    r"""Superbee limiter for the WAF flux given by:

    .. math::

        \phi(r, |c|) = \begin{cases}

            1 & if r \leq 0 \\

            1 - 2(1 - |c|)r & if 0 \leq r \leq \frac{1}{2} \\

            |c| & if \frac{1}{2} \leq r < 1 \\

            1 - (1 - |c|)r & if 1 \leq r \leq 2 \\

            2|c| - 1 & if r \geq 2

            \end{cases}
            
    """
    def limit(self, r, cabs):
        if r <= 0:
            return 1.0

        elif r > 2.0:
            return 2*cabs - 1.0
        
        elif 0 < r <= 0.5:
            return 1 - 2*r*(1 - cabs)
        
        elif 0.5 < r <= 1.0:
            return cabs

        elif 1.0 < r <= 2.0:
            return 1 - r*(1 - cabs)



limiter_functions = [

    ("Upwind (default)", UpwindLimiter),

    ("SuperBee", SuperBeeLimiter),

    ]
